package com.example.daxiguaforharmony.game;

import com.example.daxiguaforharmony.game.core.base.DisplayObject;
import com.example.daxiguaforharmony.game.core.base.DisplayObjectContainer;
import com.example.daxiguaforharmony.game.core.game.GameObject;
import com.example.daxiguaforharmony.game.core.tween.Tween;
import com.example.daxiguaforharmony.game.core.utils.Callback;
import com.example.daxiguaforharmony.game.core.utils.MathUtil;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.Fixture;

public class Fruits extends GameObject {
    protected Body _body = null;
    protected int _fruitsId = 0;
    protected int _state = 0;
    private Callback.UpdateCallback _updateCallback = null;

    public Fruits(GameScene scene, DisplayObject displayObject) {
        super(scene, displayObject);
        float sceneWidth = scene.getSceneWidth();
        float x = sceneWidth / 2f;
        float y = 200f - this._displayObject.height / 2f;
        float scale = scene.getScaleFactor();
        float radius = (this._displayObject.width / 2f) * scale;
        this._displayObject.x = x;
        this._displayObject.y = y;
        this._displayObject.scaleX = scale;
        this._displayObject.scaleY = scale;
        this._body = scene.createCircle(x, y, radius);
        this._body.m_userData = this;
        assert this._body != null;
    }

    public void updatePositionX(float x) {
        float sceneWidth = this._scene.getSceneWidth();
        float halfWidth = (this._displayObject.width * this._displayObject.scaleX) * 0.55f;
        float left = halfWidth;
        float right = sceneWidth - halfWidth;
        if (x < left) x = left;
        if (x > right) x = right;
        setPositionX(x);
    }

    @Override
    public void setPosition(float x, float y) {
        super.setPosition(x, y);
        this._body.m_xf.p.set(x / GameScene.RATE, y / GameScene.RATE);
    }

    @Override
    public void setPositionX(float x) {
        super.setPositionX(x);
        this._body.m_xf.p.set(x / GameScene.RATE, this._displayObject.y / GameScene.RATE);
    }

    public float getMinPosY() {
        float halfHeight = (this._displayObject.height * this._displayObject.scaleY) * 0.5f;
        return this._displayObject.y - halfHeight;
    }

    public void setFruitsId(int fruitsId) {
        this._fruitsId = fruitsId;
    }

    public int getFruitsId() {
        return this._fruitsId;
    }

    public void setState(int state) {
        this._state = state;
    }

    public int getState() {
        return this._state;
    }

    public void setRadius(float radius) {
        Fixture fixture = this._body.getFixtureList();
        if (fixture == null) return;
        CircleShape circle = (CircleShape) fixture.getShape();
        circle.setRadius(radius / GameScene.RATE);
        this._body.resetMassData();
    }

    public void born() {
        this._tag = 10000;
        this._body.m_type = BodyType.STATIC;
        this._body.resetMassData();
    }

    public void drop() {
        this._body.m_type = BodyType.DYNAMIC;
        this._body.m_linearVelocity.set(0f, 900f / GameScene.RATE);
        this._tag = 1000;
        this._body.resetMassData();
    }

    public void dropEnd() {
        this._tag = 100;
        this._body.m_type = BodyType.DYNAMIC;
        this._body.resetMassData();
    }

    public void idle() {
        this._body.m_type = BodyType.STATIC;
        this._body.resetMassData();
    }

    public void moveTo(float duration, float px, float py, Callback.CompleteCallback callback) {
        this.setRadius(0f);
        this._body.setActive(false);
        Tween.moveTo(this._displayObject, duration, px, py, callback);
    }

    public void killTween() {
        this._scene.removeUpdateCallbackByTarget(this);
    }

    @Override
    public void update(float dt) {
        super.update(dt);
        if (this._updateCallback != null) this._updateCallback.update(dt);
        if (this._body.getType() == BodyType.STATIC) return;
        if (this._body.isActive() == false || this._body.isAwake() == false) return;
        Fixture fixture = this._body.getFixtureList();
        if (fixture == null) return;
        CircleShape circle = (CircleShape)fixture.getShape();
        Vec2 pos = this._body.getPosition();
        this._displayObject.x = (pos.x + circle.m_p.x) * GameScene.RATE;
        this._displayObject.y = (pos.y + circle.m_p.y) * GameScene.RATE;
        float rotation = this._body.getAngle() * MathUtil.RADIAN_TO_ANGLE;
        this._displayObject.rotation = rotation;
    }

    @Override
    public void addToScene() {
        // super.addToScene();
        DisplayObjectContainer container = this._scene.getFruitsLayer();
        container.addChild(this._displayObject);
        this._scene.addGameObject(this);
    }

    @Override
    public void removeFromScene() {
        super.removeFromScene();
        this._body.setActive(false);
        this.setRadius(0f);
    }

    public void reset() {
        float sceneWidth = this._scene.getSceneWidth();
        float x = sceneWidth / 2f;
        float y = 200f - this._displayObject.height / 2f;
        float scale = this._scene.getScaleFactor();
        float radius = (this._displayObject.width / 2f) * scale;
        this._displayObject.scaleX = scale;
        this._displayObject.scaleY = scale;
        this.setPosition(x, y);
        this._tag = 0;
        this._state = 0;
        this._fruitsId = 0;
        this._body.m_type = BodyType.STATIC;
        this._body.m_userData = this;
        this._body.m_linearVelocity.set(0f, 100f / GameScene.RATE);
        this._body.m_angularVelocity = 0f;
        this._body.m_angularDamping = 0f;
        this._body.setActive(true);
        this.setRadius(radius);
    }

    @Override
    public void Destory() {
        super.Destory();
        this._scene.world.destroyBody(this._body);
        this._body = null;
    }
}
